package edu.itcs6112.za.web.controller;

import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;
import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.google.common.collect.Lists;

import edu.itcs6112.za.domain.Customer;
import edu.itcs6112.za.service.CustomerService;
import edu.itcs6112.za.web.form.CustomerGrid;
import edu.itcs6112.za.web.form.Message;
import edu.itcs6112.za.web.util.UrlUtil;
//import org.springframework.security.access.prepost.PreAuthorize;


@RequestMapping("/customers")
@Controller
public class CustomerController {

	final Logger logger = LoggerFactory.getLogger(CustomerController.class);	
	
	@Autowired
	MessageSource messageSource;
	
	@Autowired
	private CustomerService customerService;
	
	@RequestMapping(method = RequestMethod.GET)
	public String list(Model uiModel) {
		logger.info("Listing customers");	
		
		List<Customer> customers = customerService.findAll();
		uiModel.addAttribute("customers", customers);
		
		logger.info("No. of customers: " + customers.size());
		
		return "customers/list";
	}
	
	@RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public String show(@PathVariable("id") Long id, Model uiModel) {
        Customer customer = customerService.findById(id);
		uiModel.addAttribute("customer", customer);
        return "customers/show";
    }	
	
	@RequestMapping(value = "/{id}", params = "form", method = RequestMethod.POST)
    public String update(@Valid Customer customer, BindingResult bindingResult, Model uiModel, 
    		HttpServletRequest httpServletRequest, RedirectAttributes redirectAttributes, Locale locale) {
		logger.info("Updating customer");
        if (bindingResult.hasErrors()) {
        	uiModel.addAttribute("message", new Message("error", messageSource.getMessage("customer_save_fail", new Object[]{}, locale)));        	
            uiModel.addAttribute("customer", customer);
            return "customers/update";
        }
        uiModel.asMap().clear();
        redirectAttributes.addFlashAttribute("message", new Message("success", messageSource.getMessage("customer_save_success", new Object[]{}, locale)));        

       
        
        customer.setUserRole("ROLE_CUSTOMER");
        customerService.save(customer);
        return "redirect:/customers/" + UrlUtil.encodeUrlPathSegment(customer.getId().toString(), httpServletRequest);
    }	

	@RequestMapping(value = "/{id}", params = "form", method = RequestMethod.GET)
    public String updateForm(@PathVariable("id") Long id, Model uiModel) {
        uiModel.addAttribute("customer", customerService.findById(id));
        return "customers/update";
	}	
	
	@RequestMapping(params = "form", method = RequestMethod.POST)
    public String create(@Valid Customer customer, BindingResult bindingResult, Model uiModel, 
    		HttpServletRequest httpServletRequest, RedirectAttributes redirectAttributes, Locale locale) {
		logger.info("Creating customer");
        if (bindingResult.hasErrors()) {
			uiModel.addAttribute("message", new Message("error", messageSource.getMessage("customer_save_fail", new Object[]{}, locale)));
            uiModel.addAttribute("customer", customer);
            return "customers/create";
        }
        uiModel.asMap().clear();
        redirectAttributes.addFlashAttribute("message", new Message("success", messageSource.getMessage("customer_save_success", new Object[]{}, locale)));

        logger.info("Customer id: " + customer.getId());
        
        if(null == customer.getUserRole() || "" == customer.getUserRole()){
        	customer.setUserRole("ROLE_CUSTOMER");
        }
        
        customerService.save(customer);
        return "redirect:/customers/" + UrlUtil.encodeUrlPathSegment(customer.getId().toString(), httpServletRequest);
    }	
	
	//@PreAuthorize("isAuthenticated()")
	@RequestMapping(params = "form", method = RequestMethod.GET)
    public String createForm(Model uiModel) {
		Customer customer = new Customer();
        uiModel.addAttribute("customer", customer);
        return "customers/create";
    }	
	
	/**
	 * Support pagination for front-end grid
	 * @param uiModel
	 * @return
	 */
	@RequestMapping(value = "/listgrid", method = RequestMethod.GET, produces="application/json")
	@ResponseBody
	public CustomerGrid listGrid(@RequestParam(value = "page", required = false) Integer page,
			@RequestParam(value = "rows", required = false) Integer rows,
			@RequestParam(value = "sidx", required = false) String sortBy,
			@RequestParam(value = "sord", required = false) String order) {
		
		logger.info("Listing customers for grid with page: {}, rows: {}", page, rows);
		logger.info("Listing customers for grid with sort: {}, order: {}", sortBy, order);
		
		// Process order by
		Sort sort = null;
		String orderBy = sortBy;
		if (orderBy != null && orderBy.equals("firstNameString")) orderBy = "firstName";
		
		if (orderBy != null && order != null) {
			if (order.equals("desc")) {
				sort = new Sort(Sort.Direction.DESC, orderBy);
			} else
				sort = new Sort(Sort.Direction.ASC, orderBy);
		}
		
		// Constructs page request for current page
		// Note: page number for Spring Data JPA starts with 0, while jqGrid starts with 1
		PageRequest pageRequest = null;
		
		if (sort != null) {
			pageRequest = new PageRequest(page - 1, rows, sort);
		} else {
			pageRequest = new PageRequest(page - 1, rows);
		}
				
		Page<Customer> customerPage = customerService.findAllByPage(pageRequest);
		
		// Construct the grid data that will return as JSON data
		CustomerGrid customerGrid = new CustomerGrid();
		
		customerGrid.setCurrentPage(customerPage.getNumber() + 1);
		customerGrid.setTotalPages(customerPage.getTotalPages());
		customerGrid.setTotalRecords(customerPage.getTotalElements());
		customerGrid.setCustomerData(Lists.newArrayList(customerPage.iterator()));
		
		return customerGrid;
	}	
	
	

	
}
